package com.mspbots.rule.exceptions.attendance;

import cn.hutool.core.util.StrUtil;
import com.mspbots.cw.request.AttendanceDTO;
import com.mspbots.cw.request.TenantUserConfigurationDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;


/**
 * @author Dinnes
 */
@Slf4j
@Rule(name = "NotEodTooLong",
        description = "Dear {USER}, you started the day 15 hours again, but you didn't check out yet. " +
                "I assume that you forgot to check out. I just checked you out. " +
                "You can type \"EOD at [time]\" to correct the check out time. ")
public class NotEodTooLong extends AttendanceBaseRule {

    @Condition
    public boolean condition(@Fact(FACT) TenantUserConfigurationDTO tenantUserConfigurationDTO) {
        try {
            if (!setUserMapping(tenantUserConfigurationDTO.getTenantUserId())
                    || super.checkDayMessage(tenantUserConfigurationDTO.getTenantUserId())
                    || ObjectUtils.isEmpty(this.tenantRuleDTO.getRuleParams())) {
                return false;
            }

            AttendanceDTO attendanceDTOBOTOUT = getAttendance(Map.of("tenantId", tenantUserConfigurationDTO.getTenantId(),
                    "userId", tenantUserConfigurationDTO.getTenantUserId(), "type", "BOTOUT"));

//            if (!ObjectUtils.isEmpty(attendanceDTOBOTOUT) && LocalDateTime.now().minusHours(15).isBefore(attendanceDTOBOTOUT.getLogTime().minusHours(tz))) {
//                return false;
//            }

            // get last attendance
            AttendanceDTO attendanceDTOUT = getAttendance(Map.of("tenantId", tenantUserConfigurationDTO.getTenantId(),
                    "userId", tenantUserConfigurationDTO.getTenantUserId(), "type", "OUT"));

//            AttendanceDTO attendanceDTOUT = getAttendance(Map.of("tenantId",tenantUserConfigurationDTO.getTenantId(),
//                    "userId",tenantUserConfigurationDTO.getTenantUserId(),"type","OUT",
//                    "startTime",LocalDateTime.of(LocalDate.now(), LocalTime.MIN),"endTime",LocalDateTime.of(LocalDate.now(), LocalTime.MAX)));
//            if (!ObjectUtils.isEmpty(attendanceDTOUT) && LocalDateTime.now().minusHours(15).isBefore(attendanceDTOUT.getLogTime().minusHours(tz))) {
//                return false;
//            }

            AttendanceDTO attendanceDTOIN = getAttendance(Map.of("tenantId", tenantUserConfigurationDTO.getTenantId(),
                    "userId", tenantUserConfigurationDTO.getTenantUserId(), "type", "IN"));

//            AttendanceDTO attendanceDTOIN = getAttendance(Map.of("tenantId",tenantUserConfigurationDTO.getTenantId(),
//                    "userId",tenantUserConfigurationDTO.getTenantUserId(),"type","IN",
//                    "startTime",LocalDateTime.of(LocalDate.now(), LocalTime.MIN),"endTime",LocalDateTime.of(LocalDate.now(), LocalTime.MAX)));
            if (ObjectUtils.isEmpty(attendanceDTOIN)) {
                return false;
            }
            Integer Hours = this.tenantRuleDTO.getRuleParams().get("Hours").asInt();

            if (StringUtils.isEmpty(attendanceDTOBOTOUT) && StringUtils.isEmpty(attendanceDTOUT)) {
                if (logTimeUTC(attendanceDTOIN).isBefore(LocalDateTime.now().minusHours(Hours))) {
                    return true;
                }
            }

            if (!StringUtils.isEmpty(attendanceDTOBOTOUT) && attendanceDTOBOTOUT.getLogTime().isAfter(attendanceDTOIN.getLogTime())) {
                return false;
            }

            if (!StringUtils.isEmpty(attendanceDTOUT) && attendanceDTOUT.getLogTime().isAfter(attendanceDTOIN.getLogTime())) {
                return false;
            }

            //if logTime < now - hours
            if (logTimeUTC(attendanceDTOIN).isBefore(LocalDateTime.now().minusHours(Hours))) {
                return true;
            }

            return false;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("NotEodTooLong error : [{}] ", tenantUserConfigurationDTO.getTenantUserId());
        }
        return false;
    }

    @Override
    @Action
    public void action(@Fact(FACT) TenantUserConfigurationDTO tenantUserConfigurationDTO) {

        String now = LocalDateTime.now().plusHours(tz).format(DateTimeFormatter.ofPattern("MM/dd HH:mm"));

        Map<String, Object> attendanceParams = Map.of("teamsId", tenantUserMappingDTO.getTeamsUserId(),
                "type", "BOTOUT",
                "tz", tz,
                "tzStr", tzStr,
                "logTime", now,
                "tenantId", tenantUserConfigurationDTO.getTenantId(),
                "userId", tenantUserConfigurationDTO.getTenantUserId());
        this.coreClient.post("/attendances/save", attendanceParams)
                .subscribe(result -> log.info("result is {}", result), err -> log.error(err.getMessage()));

        Map<String, Object> params = new HashMap<>(16);
        params.put("USER", tenantUserMappingDTO.getFirstName());
        String message = StrUtil.format(this.tenantRuleDTO.getTemplate(), params);

        String suffixMessage = new StringBuilder()
                .append("--")
                .append("<span style='color:#999d9c;font-size:10px;'>")
                .append(suffixUserName())
                .append("[")
                .append(now)
                .append(" ").append(tzStr)
                .append("]")
                .append("</span>").toString();

        messages.setMessage(message + "<br>" + suffixEscalation() + suffixMessage);
        messages.setBusinessType("attendance");
        insertMessage(messages);
    }
}
